/// <reference path="../_all.ts" />

module Application.Controllers {

    export class PlayersController implements Application.Interfaces.Controllers.IController {
        public static $inject = [
            '$rootScope',
            '$scope',
            '$location',
            '$routeParams',
            'PlayerService',
            'TranslationService',
        ];

        playersResult: {
            (data): void;
            (data, err): void;
        };

        playerHistoriesResult: {
            (data): void;
            (data, err): void;
        };

        bansResult: {
            (data): void;
            (data, err): void;
        };

        constructor(public RootScope: Application.Interfaces.Scopes.IRootScope,
            public Scope: Application.Interfaces.Scopes.IPlayersScope,
            public Location: ng.ILocationService,
            public RouteParams: Application.Interfaces.Routing.IServerRouteParams,
            public Players: Application.Interfaces.Services.IPlayerService,
            public Translations: Application.Interfaces.Services.ITranslationService) {

                this.Scope.vm = this;
                this.Scope.user = this.RootScope.user;
                this.Scope.location = this.Location;
                this.Scope.messages = new Application.Utility.Messages();
                this.Scope.navigations = new Application.Utility.Navigations();
                this.Scope.players = <Application.Resources.IPlayer[]>[];
                this.Scope.filters = {};

                this.Scope.navigations.AddLink(Translations.Translate("SERVERLIST"), "/servers", false, false, Application.Constants.Icons.Servers);
                this.Scope.navigations.AddLink(Translations.Translate("ACTIONS"), "/actions", false, false, Application.Constants.Icons.Actions);
                this.Scope.navigations.AddLink(Translations.Translate("PLAYERS"), "/players", true, false, Application.Constants.Icons.Bans);

                if (this.Scope.user && this.Scope.user.role && this.Scope.user.role > 4) {
                    this.Scope.navigations.AddLink(Translations.Translate("USERS"), "/users", false, false, Application.Constants.Icons.Users);
                };
                this.Scope.navigations.AddLinkRight(Translations.Translate("ACCOUNT"), "/users/" + this.Scope.user.user_id, false);
                this.Scope.navigations.AddLinkRight(Translations.Translate("LOGOUT"), "/", false);

                this.playersResult = (data, err?) => {
                    this.playersResultProxy.apply(this, [data, err]);
                };

                this.playerHistoriesResult = (data, err?) => {
                    this.playerHistoriesResultProxy.apply(this, [data, err]);
                };

                this.bansResult = (data, err?) => {
                    this.bansResultProxy.apply(this, [data, err]);
                };

                this.getPlayers(this.Scope.filters);
        }

        public log(msg: string) {
            //console.log(msg);
        }

        public refresh() {
            this.getPlayers(this.Scope.filters);
        }

        public getPlayers(filters: any) {
            this.log('getPlayers');
            this.Players.GetPlayers(filters, this.playersResult);
        }

        private playersResultProxy(data, err) {
            this.log('players result');
            if (data != null) {
                var players = <Application.Resources.IPlayer[]> data;
                if (players != null && players.length > 0) {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.success, "Info", new Application.Utility.String(this.Translations.Translate('PLAYERSFOUND')).format(players.length.toString()));
                    var result: Application.Resources.IPlayer;
                    // Adding the NEW items at the top of the list and pushing down the existing ones
                    // Since we are adding at the top, it's more convenient to loop in reverse order
                    for (var i = players.length - 1; i >= 0; i--) {
                        result = players[i];
                        this.ensurePlayerBan(result);
                        // We look in the existing list if this user already existed, if it did, we remove it
                        for (var j = 0; j < this.Scope.players.length; j++) {
                            if (this.Scope.players[j].player_id == players[i].player_id) {
                                this.Scope.players.splice(j, 1);
                                break;
                            };
                        };
                        // Now we add the new user at the top
                        this.Scope.players.splice(0, 0, result);
                        // And if no old user was removed, the resulting list is probably longer than the expected one, so we clean it up
                        if (this.Scope.players.length > players.length) {
                            this.Scope.players.splice(players.length, this.Scope.players.length - players.length);
                        };
                    };
                    this.Scope.playersListForm.$setPristine();
                } else {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, "Error", this.Translations.Translate('NOPLAYERSFOUND'));
                };
            } else {
                if (err != null) {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, err.data.status + ' ' + err.data.type, err.data.message);
                } else {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, '000 Unknown', this.Translations.Translate('UNKNOWNERROR'));
                };
            };
        }

        private ensurePlayerBan(player: Application.Resources.IPlayer) {
            player.ban = <Application.Resources.IBan>{};
            player.ban.player_id = player.player_id;
            player.ban.reason = '';
            player.is_banned = false;
            player.ban_reason = '';
            if (player.bans && player.bans.length > 0) {
                for (var i = 0; i < player.bans.length; i++) {
                    if (!player.bans[i].is_lifted) {
                        player.is_banned = true;
                        player.ban_reason = player.bans[i].reason;
                        break;
                    };
                };
            };
        }

        public getPlayerHistories(player: Application.Resources.IPlayer) {
            this.log('getPlayerHistories');
            this.Players.GetPlayerHistories(player, this.playersResult);
        }

        private playerHistoriesResultProxy(data, err) {
            this.log('player histories result');
            if (data != null) {

            } else {
                if (err != null) {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, err.data.status + ' ' + err.data.type, err.data.message);
                } else {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, '000 Unknown', this.Translations.Translate('UNKNOWNERROR'));
                };
            };
        }

        public banPlayers() {
            this.log('banPlayers');
            var players = <Application.Resources.IPlayer[]>[];
            for (var i = 0; i < this.Scope.players.length; i++) {
                var player = this.Scope.players[i];
                if (player.ban.reason && player.ban.reason.length > 0) {
                    players.push(player);
                };
            };
            this.Players.BanPlayers(players, this.bansResult);
        }

        public liftPlayerBan(player: Application.Resources.IPlayer) {
            this.log('liftPlayerBan');
            this.Players.LiftPlayerBan(player, this.bansResult);
        }

        private bansResultProxy(data, err) {
            this.log('bans result');
            if (data != null) {
                if (data instanceof Array) {
                    var players = <Application.Resources.IPlayer[]> data;
                    if (players != null && players.length > 0) {
                        this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.success, "Info", new Application.Utility.String(this.Translations.Translate('PLAYERSUPDATED')).format(players.length.toString()));
                        var result: Application.Resources.IPlayer;
                        for (var i = 0; i < this.Scope.players.length; i++) {
                            result = null;
                            for (var j = 0; j < players.length; j++) {
                                if (this.Scope.players[i].player_id == players[j].player_id) {
                                    result = players[j];
                                    this.ensurePlayerBan(result);
                                    players.splice(j, 1);
                                    break;
                                };
                            };
                            if (result != null) {
                                this.Scope.players[i] = result;
                            };
                            if (players.length <= 0) {
                                break;
                            };
                        };
                        for (var i = 0; i < players.length; i++) {
                            result = players[i];
                            this.ensurePlayerBan(result);
                            this.Scope.players.push(result);
                        };
                        this.Scope.playersListForm.$setPristine();
                    } else {
                        this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, "Error", this.Translations.Translate('NOPLAYERSFOUND'));
                    };
                } else {
                    var player = <Application.Resources.IPlayer> data;
                    if (player != null) {
                        this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.success, "Info", new Application.Utility.String(this.Translations.Translate('PLAYERUPDATED')).format(player.player_name));
                        for (var i = 0; i < this.Scope.players.length; i++) {
                            if (this.Scope.players[i].player_id == player.player_id) {
                                this.ensurePlayerBan(player);
                                this.Scope.players[i] = player;
                                break;
                            };
                        };
                    } else {
                        this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, "Error", this.Translations.Translate('NOPLAYERUPDATED'));
                    };
                };
            } else {
                if (err != null) {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, err.data.status + ' ' + err.data.type, err.data.message);
                } else {
                    this.Scope.messages.AddAndGrowl(Application.Utility.MessageType.error, '000 Unknown', this.Translations.Translate('UNKNOWNERROR'));
                };
            };
        }

    };
}